package common

import (
	"archive/zip"
	"bufio"
	"fmt"
	"io"
	"log"
	"os"
	"path/filepath"
	"regexp"
	"strings"
)

func ParseAndSaveFiles(baseDir, input string) error {
	// 在创建文件前创建根目录
	if _, err := os.Stat(baseDir); os.IsNotExist(err) {
		log.Printf("目标目录 %s 不存在，尝试创建...\n", baseDir)
		if err := os.MkdirAll(baseDir, 0755); err != nil {
			return fmt.Errorf("无法创建根目录: %v", err)
		}
	}

	// 将输入字符串转换为Reader
	reader := bufio.NewReader(strings.NewReader(input))

	// 定义正则表达式匹配文件路径标记行
	// 格式: ==== 文件路径 ====
	re := regexp.MustCompile(`^====\s*([^=]+?)\s*====\r?\n?$`)

	var (
		currentPath string
		currentFile *os.File
		line        string
		err         error
		isEOF       bool
	)

	for !isEOF {
		line, err = reader.ReadString('\n')
		// fmt.Println(line)
		if err != nil {
			// 处理读取结束
			if err != io.EOF {
				return err
			}
			isEOF = true
			log.Println("处理读取结束")
			// 最后一行是空内容则跳过
			if line == "" {
				break
			}
		}

		// 尝试匹配文件路径标记
		matches := re.FindStringSubmatch(line)
		if matches != nil {
			// 发现新的文件路径标记
			log.Println("发现新的文件路径标记")
			path := matches[1]
			fullPath := filepath.Join(baseDir, path)

			// 关闭前一个文件（如果存在）
			if currentFile != nil {
				if err := currentFile.Close(); err != nil {
					return fmt.Errorf("关闭文件 %s 失败: %w", currentPath, err)
				}
				log.Printf("文件保存: %s\n", currentPath)
			}

			// 为当前路径创建目录
			if err := os.MkdirAll(filepath.Dir(fullPath), os.ModePerm); err != nil {
				return fmt.Errorf("创建目录 %s 失败: %w", filepath.Dir(fullPath), err)
			}

			// 打开新文件
			currentFile, err = os.Create(fullPath)
			if err != nil {
				return fmt.Errorf("创建文件 %s 失败: %w", fullPath, err)
			}
			currentPath = fullPath
			log.Printf("创建文件: %s\n", fullPath)
			continue
		}

		// 如果当前有打开的文件，写入内容
		if currentFile != nil {
			// 写入时保留原有的行尾换行符
			if _, err := currentFile.WriteString(line); err != nil {
				return fmt.Errorf("写入文件 %s 失败: %w", currentPath, err)
			}
		}
	}

	// 关闭最后一个文件（如果存在）
	if currentFile != nil {
		if err := currentFile.Close(); err != nil {
			return fmt.Errorf("关闭文件 %s 失败: %w", currentPath, err)
		}
		log.Printf("文件保存: %s\n", currentPath)
	}

	return nil
}

// WalkDir 返回目录下所有文件的列表
func WalkDir(root, baseDir string, pathList []string) ([]string, error) {

	entries, err := os.ReadDir(root)
	if err != nil {
		return pathList, err
	}

	for _, entry := range entries {
		fullPath := filepath.Join(root, entry.Name())
		if entry.IsDir() {
			relPath, _ := filepath.Rel(baseDir, fullPath)
			pathList = append(pathList, relPath)
			pathList, err = WalkDir(fullPath, baseDir, pathList) // 递归子目录
			if err != nil {
				return pathList, err
			}
		} else {
			relPath, _ := filepath.Rel(baseDir, fullPath)
			pathList = append(pathList, relPath)
		}
	}
	return pathList, nil
}

// AddFilesToZip 将指定路径的文件添加到ZIP
func AddFilesToZip(zipWriter *zip.Writer, basePath string) error {
	return filepath.Walk(basePath, func(filePath string, info os.FileInfo, err error) error {
		if err != nil {
			return err
		}

		// 跳过目录
		if info.IsDir() {
			return nil
		}

		// 获取相对路径
		relPath, err := filepath.Rel(basePath, filePath)
		if err != nil {
			return err
		}
		relPath = filepath.ToSlash(relPath) // 统一为Linux路径分隔符

		// 创建ZIP条目
		zipEntry, err := zipWriter.Create(relPath)
		if err != nil {
			return err
		}

		// 打开并拷贝文件内容
		file, err := os.Open(filePath)
		if err != nil {
			return err
		}
		defer file.Close()

		_, err = io.Copy(zipEntry, file)
		return err
	})
}

// AddFileToZip 将指定路径的文件添加到ZIP
func AddFileToZip(zipWriter *zip.Writer, path string) error {
	fileInfo, err := os.Stat(path)
	if err != nil {
		return fmt.Errorf("文件不存在: " + err.Error())
	}

	if fileInfo.IsDir() {
		return fmt.Errorf("指定路径是目录而不是文件")
	}

	// 创建ZIP条目
	zipEntry, err := zipWriter.Create(filepath.Base(path))
	if err != nil {
		return fmt.Errorf("创建ZIP条目失败: " + err.Error())
	}

	// 打开源文件
	file, err := os.Open(path)
	if err != nil {
		return fmt.Errorf("打开文件失败: " + err.Error())
	}
	defer file.Close()

	// 拷贝文件内容到ZIP
	_, err = io.Copy(zipEntry, file)
	if err != nil {
		return fmt.Errorf("写入ZIP文件失败: " + err.Error())
	}

	return nil
}
